package go;

import archivos.Txt;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import utils.OS;

/**
 * @file TreeGO.java
 * @author Juan Humanes Ferrer
 * @date 04-Marzo-2014
 */
public class TreeGO {

    private List<GO_term> terminos;
    private final String org;

    public String getOrg() {
        return org;
    }
    private String raiz;
    private String sesion;

    public List<String> getGenes() {
        return genes;
    }

    public void setGenes(List<String> genes) {
        this.genes = genes;
    }
    private List<String> genes;

    public TreeGO(String raiz, String sesion, String org) {
        String separator = OS.getDirectorySeparator();
        this.terminos = new ArrayList();
        this.raiz = raiz;
        this.sesion = sesion;
        File orgGO = new File(raiz + separator + "orgGO.txt");
        this.org = Txt.orgGoganpa(org, orgGO);
        this.genes = new ArrayList();
    }

    

    /**
     * Método devuelve la de terminos GO de la ontologia BP
     *
     * @return terminos
     */
    public List<GO_term> getTerminos() {
        return terminos;
    }

    /**
     * Método modifica la de terminos GO de la ontologia BP
     *
     * @param terminos
     */
    public void setTerminos(List<GO_term> terminos) {
        this.terminos= terminos;
    }

    /**
     * Método devuelve la ruta de la carpeta temporal
     *
     * @return raiz
     */
    public String getRaiz() {
        return raiz;
    }

    /**
     * Método que modifica la ruta de la carpeta temporal
     *
     * @param raiz
     */
    public void setRaiz(String raiz) {
        this.raiz = raiz;
    }

    /**
     * Método devuelve la sesion de usuario
     *
     * @return sesion
     */
    public String getSesion() {
        return sesion;
    }

    /**
     * Método modifica la sesion de usuario
     *
     * @param sesion
     */
    public void setSesion(String sesion) {
        this.sesion = sesion;
    }

    
    /**
     * Método que añade los terminos de una ontologia de GO, a partir de los
     * datos del fichero resultante de la llamada a R que devuelve una lista de
     * terminos con los hijos de cada uno, siendo el termino base el elegido por
     * el usuario
     *
     * @param ontologia
     * @param term
     * @throws java.lang.InterruptedException
     */
    public void addTerminos(String ontologia, String term) throws InterruptedException {
        boolean enc = false;
        boolean fin = false;
        FileReader fr = null;
        BufferedReader br = null;

        try {
            String separator = OS.getDirectorySeparator();

            fr = new FileReader(getRaiz() + separator + "go" + separator + getSesion() + separator + ontologia + ".txt");
            br = new BufferedReader(fr);
            // Lectura del fichero
            String linea;

            while (((linea = br.readLine()) != null) && !fin) {
                String[] l = linea.split(" ");
                if (l[0].equals(term)) {

                    enc = true;
                    GO_term termino = new GO_term(l[0]);
                    int pos = existeTermino(termino.getName(), ontologia);
                    GO_term hijo = new GO_term(l[2]);
                    
                            if (pos == -1) {
                                List<String> lgenes = Txt.genesTermino(termino.getName(), ontologia, getRaiz() + separator + "go" + separator + getSesion());
                                
                                this.listaGenes(lgenes);
                                this.terminos.add(termino);
                                if (!hijo.getName().equals("NA")) {
                                    this.terminos.get(terminos.size() - 1).getHijos().add(hijo);
                                    addTerminos(ontologia, l[2]);
                                }

                            } else {
                                if (!hijo.getName().equals("NA")) {
                                    this.terminos.get(pos).getHijos().add(hijo);
                                    addTerminos(ontologia, l[2]);
                                }
                            }
                            

                } else {
                    if (enc == true) {
                        fin = true;
                    }
                }
            }
        } catch (IOException e) {
        } finally {
            // En el finally cerramos el fichero, para asegurarnos
            // que se cierra tanto si todo va bien como si salta 
            // una excepcion.
            try {
                if (null != fr) {
                    fr.close();
                }
            } catch (IOException e2) {
            }
        }

    }

    /**
     * Método que determina si existe un termino en una ontologia
     *
     * @param name nombre del termino
     * @param ontologia
     * @return existe : devuelve la posicion del termino en la lista
     */
    public int existeTermino(String name, String ontologia) {
        int existe = -1;
        int cont = -1;
            for (GO_term termino : terminos) {
                cont++;
                if (termino.getName().equals(name)) {
                    existe = cont;
                    break;
                }
            }
        
       
        return existe;
    }
    
     public void listaGenes(List<String> lgenes) {
        
        for (String lgene : lgenes) {
            if (this.genes.contains(lgene)) {
            } else {
                this.genes.add(lgene);
            }
        }
            
        
    }

}
